﻿using System;
using System.Xml.Linq;
using NJabber.Stream.Elements;
using NUnit.Framework;

namespace NJabber.Stream.Elements
{
    [TestFixture]
    public class PresenceStanzaTest : StanzaTestBase
    {
        public PresenceStanzaTest() : base("presence", "", "")
        { }

        #region Write method test

        [Test]
        public void Write_NotEmptyAvailabilityValue_WritesCorrectXml()
        {
            PresenceStanza element = new PresenceStanza();
            XElement expectedElement = CreateStanzaXElement("presence", "");

            expectedElement.Add(new XElement("show", "dnd"));
            element.Availability = AvailabilityType.DoNotDisturb;

            VerifyWriteOutput(expectedElement, element);
        }

        [Test]
        public void Write_NotEmptyStatusTextValue_WritesCorrectXml()
        {
            string statusText = "status_text";
            PresenceStanza presenseElement = new PresenceStanza();
            XElement expectedElement = new XElement(presenseElement.Name, new XElement("status", statusText));
            presenseElement.StatusText = statusText;
            VerifyWriteOutput(expectedElement, presenseElement);
        }

        [Test]
        public void Write_NotNullPriorityValue_WritesCorrectXml()
        {
            int priority = 123;
            PresenceStanza presenceElement = new PresenceStanza();
            XElement expectedElement = new XElement(presenceElement.Name, new XElement("priority", priority));
            presenceElement.Priority = priority;
            VerifyWriteOutput(expectedElement, presenceElement);
        }

        #endregion

        #region Equals method tests

        [Test]
        public void Equals_DifferentAvailability_ReturnsFalse()
        {
            PresenceStanza presence1 = new PresenceStanza { Availability = "av1" };
            PresenceStanza presence2 = new PresenceStanza { Availability = "av2" };

            Assert.That(presence1.Equals(presence2), Is.False);
        }

        [Test]
        public void Equals_SameAvailability_ReturnsTrue()
        {
            PresenceStanza presence1 = new PresenceStanza { Availability = "av8" };
            PresenceStanza presence2 = new PresenceStanza { Availability = "av8" };

            Assert.That(presence1.Equals(presence2), Is.True);
        }

        [Test]
        public void Equals_DifferentPriorities_ReturnsFalse()
        {
            PresenceStanza presence1 = new PresenceStanza {Priority = 8};
            PresenceStanza presence2 = new PresenceStanza {Priority = 10};

            Assert.That(presence1.Equals(presence2), Is.False);
        }

        [Test]
        public void Equals_SamePriorities_ReturnsTrue()
        {
            PresenceStanza presence1 = new PresenceStanza {Priority = 8};
            PresenceStanza presence2 = new PresenceStanza {Priority = 8};

            Assert.That(presence1.Equals(presence2), Is.True);
        }

        [Test]
        public void Equals_DifferentStatusText_ReturnsFalse()
        {
            PresenceStanza presence1 = new PresenceStanza {StatusText = "status1"};
            PresenceStanza presence2 = new PresenceStanza {StatusText = "status2"};

            Assert.That(presence1.Equals(presence2), Is.False);
        }

        [Test]
        public void Equals_SameStatusText_ReturnsTrue()
        {
            PresenceStanza presence1 = new PresenceStanza {StatusText = "I'm happy"};
            PresenceStanza presence2 = new PresenceStanza {StatusText = "I'm happy"};

            Assert.That(presence1.Equals(presence2), Is.True);
        }

        #endregion

        [Test]
        [ExpectedException(typeof(ArgumentException))]
        public void Priority_ValueGreaterThenMaxValue_ThrowsException()
        {
            PresenceStanza stanza = new PresenceStanza();
            stanza.Priority = PresenceStanza.MaxPriorityValue + 1;
        }

        [Test]
        [ExpectedException(typeof(ArgumentException))]
        public void Priority_ValueGreaterThenMinValue_ThrowsException()
        {
            PresenceStanza stanza = new PresenceStanza();
            stanza.Priority = PresenceStanza.MinPriorityValue - 1;
        }
    }
}
